﻿using System;
using System.Collections.Generic;
using System.Text;
using AccountManager.TableModel.Model;
using AccountManager.Runtime;
using AccountManager.AL.Enums;
using ZhCun.Framework.Common.Models;

namespace AccountManager.AL
{
    public class ALJiZhangView : ALBase
    {
        public class ConsumeSearchModel
        {
            public DateTime StartTime { set; get; }
            public DateTime EndTime { set; get; }
            public string ConsumeName { set; get; }
            public string ConsumeType { set; get; }
            public int BalanceType { set; get; }
            public string Account { set; get; }
            public bool IsAddTime { set; get; }
        }

        public List<VConsume> GetConsumeData(ConsumeSearchModel serModel)
        {
            CommonSearch.Clear();
            string timeColumn = serModel.IsAddTime ? VConsume.CNAddTime : VConsume.CNConsumeDate;
            CommonSearch
                    .And(timeColumn).GreaterThenEqual(serModel.StartTime.ToString("yyyy-MM-dd"))
                    .And(timeColumn).LessThan(serModel.EndTime.AddDays(1).ToString("yyyy-MM-dd"));
            CommonSearch.OrderByDesc(timeColumn);

            if (!string.IsNullOrEmpty(serModel.ConsumeName))
            {
                CommonSearch.And(VConsume.CNConsumeName).LikeFull(serModel.ConsumeName);
            }
            if (!string.IsNullOrEmpty(serModel.ConsumeType))
            {
                CommonSearch.And(VConsume.CNConsumeTypeId).Equal(serModel.ConsumeType);
            }
            if (serModel.BalanceType != 0)
            {
                CommonSearch.And(VConsume.CNBalanceTypeId).Equal(serModel.BalanceType);
            }
            if (!string.IsNullOrEmpty(serModel.Account))
            {
                CommonSearch.And(VConsume.CNAccountId).Equal(serModel.Account);
            }
            CommonSearch.And(VConsume.CNIsCancel).Equal(false);
            CommonSearch.And(VConsume.CNBalanceTypeId).In(EnBalanceType.ShouRu, EnBalanceType.ZhiChu);
            List<VConsume> rList = DA.GetList<VConsume>(CommonSearch);
            return rList;
        }

        bool AddConsume(TConsume model, EnBalanceType balanceType, out string errMsg)
        {
            if (string.IsNullOrEmpty(model.AccountId))
            {
                errMsg = "请选择账户!";
                return false;
            }
            if ((int)balanceType == 0)
            {
                errMsg = "请选择资金类型!";
                return false;
            }
            if (string.IsNullOrEmpty(model.ConsumeTypeId))
            {
                errMsg = "请选择账目类型!";
                return false;
            }
            if (model.Amount == 0)
            {
                errMsg = "发生额非法!";
                return false;
            }
            errMsg = null;
            try
            {
                DA.TransStart();
                //账户更新
                TAccount accountModel = DA.GetModel<TAccount>(model.AccountId);
                accountModel.UseCount++;
                accountModel.LastTime = GetNowTime();

                if (balanceType == EnBalanceType.ShouRu)
                {
                    model.Amount = Math.Abs(model.Amount);
                }
                else if (balanceType == EnBalanceType.ZhiChu)
                {
                    model.Amount = Math.Abs(model.Amount) * -1;
                }
                else
                {
                    throw new Exception("资金类型错误");
                }
                accountModel.Balance += model.Amount;
                DA.Update<TAccount>(accountModel, TAccount.CNBalance, TAccount.CNLastTime, TAccount.CNUseCount);

                //消费流水新增
                model.Balance += accountModel.Balance;
                model.Id = GetGuid();
                model.AddTime = GetNowTime();
                model.LastTime = GetNowTime();
                model.BalanceTypeId = ((int)balanceType);
                model.OperatorId = LoginInfo.OperatorId;
                model.IsCancel = false;
                DA.Add(model);
                //消费类型使用次数更新及最后更新时间
                TConsumeType cTypeModel = DA.GetModel<TConsumeType>(model.ConsumeTypeId);
                cTypeModel.UseCount++;
                cTypeModel.LastTime = GetNowTime();
                DA.Update(cTypeModel, TConsumeType.CNUseCount, TConsumeType.CNLastTime);

                DA.TransCommit();
                return true;
            }
            catch (Exception ex)
            {
                DA.TransRollback();
                errMsg = ex.Message;
                return false;
            }
        }
        /// <summary>
        /// 支出记账
        /// </summary>
        public bool AddOutConsume(TConsume model, out string errMsg)
        {
            return AddConsume(model, EnBalanceType.ZhiChu, out errMsg);
        }
        /// <summary>
        /// 收入记账
        /// </summary>
        public bool AddInConsume(TConsume model, out string errMsg)
        {
            return AddConsume(model, EnBalanceType.ShouRu, out errMsg);
        }
        /// <summary>
        /// 冲账
        /// </summary>
        public bool ChongZhang(VConsume viewModel, out string errMsg)
        {
            TConsume model = DA.GetModel<TConsume>(viewModel.Id);
            errMsg = null;
            EnBalanceType chongZhangLeiXing = (EnBalanceType)model.BalanceTypeId;
            switch (chongZhangLeiXing)
            {
                case EnBalanceType.ZhiChu:
                    chongZhangLeiXing = EnBalanceType.ZhiChuChongZhang;
                    break;
                case EnBalanceType.ShouRu:
                    chongZhangLeiXing = EnBalanceType.ShouRuChongZhang;
                    break;
                case EnBalanceType.ZhiChuChongZhang:
                case EnBalanceType.ShouRuChongZhang:
                default:
                    errMsg = "冲账类型错误!";
                    return false;
            }
            try
            {
                DA.TransStart();
                //修改原记录标记已冲账
                model.LastTime = GetNowTime();
                model.IsCancel = true;
                DA.Update(model, TConsume.CNLastTime, TConsume.CNIsCancel);
                //更新账户信息
                TAccount actModel = DA.GetModel<TAccount>(model.AccountId);
                switch (chongZhangLeiXing)
                {
                    case EnBalanceType.ZhiChu:
                    case EnBalanceType.ShouRu:
                        throw new Exception("资金类型错误!");
                    case EnBalanceType.ZhiChuChongZhang:
                        actModel.Balance += Math.Abs(model.Amount);
                        break;
                    case EnBalanceType.ShouRuChongZhang:
                        actModel.Balance -= Math.Abs(model.Amount);
                        break;
                    default:
                        break;
                }
                actModel.LastTime = GetNowTime();
                DA.Update<TAccount>(actModel, TAccount.CNLastTime, TAccount.CNBalance);

                //新增负记录
                model.Id = GetGuid();
                model.AddTime = GetNowTime();
                model.BalanceTypeId = (int)chongZhangLeiXing;
                model.Amount = model.Amount * -1;
                model.Balance = actModel.Balance;
                DA.Add(model);

                DA.TransCommit();
                return true;
            }
            catch (Exception ex)
            {
                DA.TransRollback();
                errMsg = ex.Message;
                return false;
            }
        }
        /// <summary>
        /// 编辑流水信息
        /// </summary>
        public bool EditConsume(TConsume model, out string errMsg)
        {
            errMsg = null;
            model.LastTime = GetNowTime();
            DA.Update(model,
                TConsume.CNConsumeDate,
                TConsume.CNConsumeName,
                TConsume.CNConsumeTypeId,
                TConsume.CNLastTime,
                TConsume.CNRemark);
            return true;
        }
        /// <summary>
        /// 撤销当天最后一笔记录
        /// </summary>
        public bool UndoLastAccount(out string errMsg)
        {
            errMsg = null;
            CommonSearch.Clear();
            DateTime nowTime = GetNowTime();
            CommonSearch
                .Add(TConsume.CNAddTime).GreaterThenEqual(nowTime.ToString("yyyy-MM-dd"))
                .And(TConsume.CNBalanceTypeId).In((int)EnBalanceType.ShouRu, (int)EnBalanceType.ZhiChu);
            CommonSearch.OrderByDesc(TConsume.CNAddTime);
            List<TConsume> rList = DA.GetListTopCount<TConsume>(1, CommonSearch);
            if (rList == null || rList.Count != 1)
            {
                errMsg = "当日没有要撤销的收入或支出的记录!";
                return false;
            }
            try
            {
                DA.TransStart();
                TConsume undoModel = rList[0];
                TAccount actModel = DA.GetModel<TAccount>(undoModel.AccountId);
                actModel.Balance -= undoModel.Amount;
                actModel.LastTime = GetNowTime();
                DA.Delete<TConsume>(undoModel.Id);
                DA.Update<TAccount>(actModel, TAccount.CNBalance, TAccount.CNLastTime);
                DA.TransCommit();
                return true;
            }
            catch (Exception ex)
            {
                DA.TransRollback();
                errMsg = "操作数据库发生异常,详情请查看日志!";
                return false;
            }
        }
    }
}